<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

require_once APPPATH . 'models/m_select.php';

/**
 * Модель для поиска и выборок записей из таблицы базы данных
 * Расширяет M_Select
 *
 * @package CoreFramework
 * @version 1.0
 * @author Gennadiy Kozlenko
 */
class M_Table extends M_Select {
   
   /**
    * Название таблицы
    *
    * @access private
    * @var string
    */
   var $_table = '';
   
   /**
    * Название полей
    *
    * @access private
    * @var string
    */
   var $_fieldsString = '*';
   
   /**
    * Массив разрешенных сравнений для ограничений поиска
    *
    * @access private
    * @var array
    */
   var $_comparisons = array('=', '<>', '<', '>', '<=', '>=', 'LIKE');
   
   /**
    * Массив ограничений
    *
    * @access private
    * @var array
    */
   var $_restrictions = array();
   
   /**
    * Конструктор класса
    *
    * @access public
    * @return M_Table
    */
   function M_Table() {
      parent::M_Select();
   } // end M_Table
   
   /**
    * Установка таблицы, с которой будем работать
    *
    * @access public
    * @param string $table
    */
   function set_table($table) {
      $this->clean();
      $this->_table = $table;
      $sql = "SELECT {$this->_fieldsString} FROM " . $this->db->dbprefix($table);
      parent::set_sql($sql);
   } // end set_table
   /**
    * Установка полей для выборки
    *
    * @access public
    * @param string $table
    */
   function set_fields($fields) {
      $this->_fieldsString = $fields;
   } // end set_table
   
   /**
    * Установка SQL запроса
    *
    * @access public
    * @param string $table
    */
   function set_sql($sql) {
      
   } // end set_sql
   
   /**
    * Получение названия таблицы
    *
    * @access public
    * @return string
    */
   function get_table() {
      return $this->_table;
   } // end get_table
   
   /**
    * Очищение данных предыдущей работы
    *
    * @access public
    */
   function clean() {
      $this->clean_restrictions();
      parent::clean();
   } // end clean
   
   /**
    * Очистка ограничений выборки
    *
    * @access public
    */
   function clean_restrictions() {
      $this->_restrictions = array();
   } // end clean_restrictions
   
   /**
    * Добавление ограничения выборки
    *
    * @access public
    * @param string $field
    * @param mixed $value
    * @param string $compare
    * @return boolean
    */
   function add_restriction($field, $value, $compare = '=') {
      $compare = strtoupper($compare);
      if (!isset($this->_fields[$field]) || !in_array($compare, $this->_comparisons)) {
         return false;
      }
      // Видоизменяем сравнительные операции
      switch ($compare) {
         case '=':
            if (null === $value) {
               $compare = 'IS';
            } elseif (is_array($value)) {
               $compare = 'IN';
            }
            break;
         case '<>':
            if (null === $value) {
               $compare = 'IS NOT';
            } elseif (is_array($value)) {
               $compare = 'NOT IN';
            }
            break;
      }
      $restriction = array(
         'field'   => $field,
         'value'   => $value,
         'compare' => $compare
      );
      array_push($this->_restrictions, $restriction);
      return true;
   } // end add_restriction
   
   /**
    * Получение массива ограничений поиска
    *
    * @access public
    * @return array
    */
   function get_restrictions() {
      return $this->_restrictions;
   } // end get_restrictions
   
   /**
    * Загрузка результатов из базы
    *
    * @access public
    * @return boolean
    */
   function load_results() {
      $this->clean_results();
      if (empty($this->_table)) {
         return false;
      }
      // Формируем запрос
      $this->_sql = "SELECT " . $this->_build_select_statement();
      $from = $this->_build_from_statement();
      if (!empty($from)) {
         $this->_sql .= " FROM " . $from;
      }
      $where = $this->_build_where_statement();
      if (!empty($where)) {
         $this->_sql .= " WHERE " . $where;
      }
      $group = $this->_build_group_statement();
      if (!empty($group)) {
         $this->_sql .= " GROUP BY " . $group;
      }
      return parent::load_results();
   } // end load_results
   
   /**
    * Метод генерации select части sql запроса
    *
    * @access protected
    * @return string
    */
   function _build_select_statement() {
      $sql = "*";
      return $sql;
   } // end _build_select_statement
   
   /**
    * Метод генерации from части sql запроса
    *
    * @access protected
    * @return string
    */
   function _build_from_statement() {
      $sql = $this->db->dbprefix($this->_table);
      return $sql;
   } // end _build_from_statement
   
   /**
    * Метод генерации where части sql запроса
    *
    * @access protected
    * @return string
    */
   function _build_where_statement() {
      // Получаем рестрикшены в виде SQL сегментов
      $restrictions = array();
      foreach ($this->_restrictions as $restriction) {
         $field = $this->db->escape_str($restriction['field']);
         $compare = $this->db->escape_str($restriction['compare']);
         $value = '';
         if (is_array($restriction['value'])) {
            $values = array();
            foreach ($restriction['value'] as $val) {
               array_push($values, $this->db->escape($val));
            }
            $value = "(" . implode(", ", $values) . ")";
         } else {
            $value = $this->db->escape($restriction['value']);
         }
         array_push($restrictions, $field . " " . $compare . " " . $value);
      }
      $sql = implode(" AND ", $restrictions);
      return $sql;
   } // end _build_where_statement
   
   /**
    * Метод генерации group части sql запроса
    *
    * @access protected
    * @return string
    */
   function _build_group_statement() {
      $sql = "";
      return $sql;
   } // end _build_group_statement
   
}
